package org.dromara.common.mybatis.handler

import cn.hutool.http.HttpStatus
import io.github.oshai.kotlinlogging.KotlinLogging
import jakarta.servlet.http.HttpServletRequest
import org.dromara.common.core.domain.R
import org.dromara.common.core.domain.R.Companion.fail
import org.dromara.common.core.utils.StringUtils
import org.mybatis.spring.MyBatisSystemException
import org.springframework.dao.DuplicateKeyException
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.RestControllerAdvice

/**
 * Mybatis异常处理器
 *
 * @author Lion Li
 * @updater LikeYouDo
 * @date 2025/1/27 2:37
 */
@RestControllerAdvice
class MybatisExceptionHandler {
    companion object {
        private val log = KotlinLogging.logger { }
    }

    /**
     * 主键或UNIQUE索引，数据重复异常
     */
    @ExceptionHandler(DuplicateKeyException::class)
    fun handleDuplicateKeyException(e: DuplicateKeyException, request: HttpServletRequest): R<Void?> {
        val requestURI = request.requestURI
        log.error { "请求地址'${requestURI}',数据库中已存在记录'${e.message}'" }
        return fail(HttpStatus.HTTP_CONFLICT, "数据库中已存在该记录，请联系管理员确认")
    }

    /**
     * Mybatis系统异常 通用处理
     */
    @ExceptionHandler(MyBatisSystemException::class)
    fun handleCannotFindDataSourceException(e: MyBatisSystemException, request: HttpServletRequest): R<Void?> {
        val requestURI = request.requestURI
        val message = e.message
        if (StringUtils.contains(message, "CannotFindDataSourceException")) {
            log.error { "请求地址'${requestURI}', 未找到数据源" }
            return fail(HttpStatus.HTTP_INTERNAL_ERROR, "未找到数据源，请联系管理员确认")
        }
        log.error(e) { "请求地址'${requestURI}', Mybatis系统异常" }
        return fail(HttpStatus.HTTP_INTERNAL_ERROR, message)
    }
}
